package chat.fullduplex;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/** 
 * This is an evolution of the original half-duplex client (@see chat.EchoClient) for full
 * duplex communication, by placing the blocking read loops in separate threads.
 * 
 * @see chat.fullduplex.EchoServer for more details.
 * @author Lom Hillah
 * @author Justin Templemore
 *
 */
public class EchoClient implements LocalChatEndPoint
{
	// TCP conxn to server
	private Socket socketToServer = null;
	// used during quit to ensure it only quits once
	private boolean isActive = true;

	/**
	 * The main has been rewritten to create an object that implements the client
	 * logic. This is good practice : Main should do nothing, only objects should work.
	 * Trust me, it avoids lots of problems (notably related to the static context) later on.
	 */
	public static void main (String[] args) 
	{
		new EchoClient().go();
		// Have a look at when this message is displayed.
		// Remember : In Java, the program finishes when the main thread AND all non daemon threads
		// have terminated.
		System.out.println("Finished client main thread");
	}

	/**
	 * Client logic of the simple chat program.
	 */
	public void go () 
	{
		try 
		{
			// local host information (very useful for setting up a conxn)
			InetAddress localhost = InetAddress.getLocalHost();
			System.out.println ("Local host  is " + localhost);

			//byte[] serverAddr = { (byte) 192, (byte) 168, 0, 58 };
			//byte[] serverAddr = { (byte) 127, (byte) 0, (byte) 0, (byte) 1 };
			String serverName = "localhost";

			// try to open a TCP connection to the server host on port 4444.
			//socketToServer = new Socket(InetAddress.getByAddress(serverAddr), 4444);
			socketToServer = new Socket (InetAddress.getByName(serverName), 4444);
		} 
		catch (UnknownHostException e) 
		{
			System.err.println ("Don't know about specified host");
			System.exit(1);
		} 
		catch (IOException e) 
		{
			System.err.println ("Couldn't get I/O for the connection to the specified host.");
			System.exit(1);
		}
		
		// Start the read loops in two separate thread. See EchoServer for explanations.
		Thread t = new Thread (new ReadFromConsole (socketToServer, this));
		t.setDaemon(true);
		t.start();
		new Thread (new ReadFromRemote (socketToServer, this)).start();
	}

	@Override
	public void quit() 
	{
		// use a flag to ensure that the quit happens only once
		if (isActive)
		{
			System.out.println ("Quitting client");
			isActive = false;
			try 
			{
				socketToServer.close();
			} 
			catch (IOException e) 
			{
				// ignore errors on close
			}
		}
	}
}
